﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SHKF.B2C.BaseHosted;
using SHKF.B2C.MeiTuanPeiSong.BLL;
using SHKF.B2C.MeiTuanPeiSong.Model;
using SHKF.B2C.MeiTuanPeiSong.Model.CallBack;
using SHKF.B2C.MeiTuanPeiSong.Model.Dto;
using SHKF.B2C.MeiTuanPeiSong.Model.Dto.Order;
using SHKF.B2C.MeiTuanPeiSong.Model.Dto.Order.Check;
using SHKF.B2C.MeiTuanPeiSong.Model.Dto.Order.Pre;
using SHKF.B2C.MeiTuanPeiSong.Model.Dto.Order.RiderLocation;
using SHKF.B2C.MeiTuanPeiSong.Model.Entity.Order;
using SHKF.B2C.MeiTuanPeiSong.Model.Entity.Shop;
using SHKF.B2C.MeiTuanPeiSong.Model.Request;
using SHKF.B2C.MeiTuanPeiSong.Network;
using SHKF.B2C.Model;
using SHKF.B2C.Model.Dto;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace SHKF.B2C.MeiTuanPeiSong.Service.Controllers
{
    //美团配送  
    [Route("[controller]")]
    [ApiController]
    public class OrderController : BaseController
    {
        private readonly HttpClientMeiTuanPeiSong httpClient;
        private readonly OrderContentBLL orderContentBLL;
        private readonly ShopBLL shopBLL;

        public OrderController(HttpClientMeiTuanPeiSong httpClient, 
            OrderContentBLL orderContentBLL,
            ShopBLL shopBLL,
            ILogger<OrderController> logger):base(logger)
        {
            this.httpClient = httpClient;
            this.orderContentBLL = orderContentBLL;
            this.shopBLL = shopBLL;
        }

        private CreateOrderByShopRequest createTest()
        {
            CreateOrderByShopRequest request = new CreateOrderByShopRequest();
            request.shop_id = "test_0001";
            request.receiver_name = "王鹏";
            request.receiver_address = "长春";
            request.receiver_phone = "1350000";
            request.receiver_lng = (int)(81.552887 * Math.Pow(10, 6));
            request.receiver_lat = (int)(36.937819 * Math.Pow(10, 6));

            request.goods_value = 100; //货物价格，单位为元 
            request.goods_weight = 0.5; //货物重量，单位为kg，精确到小数点后两位
            request.delivery_service_code = 4002;
            request.delivery_qr_code = "abc";
            request.goods_length = 65;
            request.goods_width = 50;
            request.goods_height = (double)40;

            request.goods_pickup_info = "abc";
            request.goods_delivery_info = "def";
            request.note = "abcde";
            request.invoice_title = "deeeee";

            request.tip_amount = 0;
            request.goods_code_switch = 0;
            request.coupons_id = "";

            goods_detail detail = new goods_detail();
            //detail.goods = new List<OrderDetailEntity>();
            //detail.goods.Add(new good() { goodCount = 1, goodName = "abc", goodPrice = 0.01, goodUnit = "合" });
            //request.goods_detail = detail;
             

            return request;
        }

        [HttpGet("list")]
        public OrderListDto List(string shopID, string orderID, int status, DateTime startDate, DateTime endDate)
        {
            OrderListDto dto = new OrderListDto();
            try
            { 
                List<OrderContentEntity> orderList = this.orderContentBLL.Query(shopID, orderID, status, startDate, endDate);
                dto.data = orderList; 
            }
            catch (Exception ex)
            {
                dto.SetException(ex);
            }

            return dto;
        }

        [HttpGet("detail/list")]
        public OrderDetailListDto DetailList(long SN)
        {
            OrderDetailListDto dto = new OrderDetailListDto();
            try
            {
                List<OrderDetailEntity> orderList = this.orderContentBLL.QueryDetail(SN);
                dto.data = orderList;
            }
            catch (Exception ex)
            {
                dto.SetException(ex);
            }

            return dto;
        }

        /// <summary>
        /// 预发单接口
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("preCreateByShop")]
        public async Task<MtpsPreOrderDto> PreCreateByShop(OrderContentEntity request)
        {
            MtpsPreOrderDto dto = new MtpsPreOrderDto();

            string shop_id = request.shop_id;
            ShopMtpsEntity shop = this.shopBLL.Get(shop_id);
            string msg = this.CheckOrderInfo(shop, request);
            if (msg != "")
            {
                dto.error = new Error() { code = -1, msg = msg };
                return dto;
            }

            if (request.delivery_id == 0)
            {
                request.delivery_id = DateTimeUtil.DateTimeToTimeStamp(DateTime.Now);
            }

            //定单
            if (string.IsNullOrEmpty(request.order_id))
            { 
                //request.poi_seq = this.orderContentBLL.GetOrderID(shop_id, out order_id).ToString();
                request.order_id = Guid.NewGuid().ToString("N"); ;
            }

            request.coordinate_type = 0;
            if (string.IsNullOrEmpty(request.outer_order_source_desc))
            {
                request.outer_order_source_desc = "裕林医药零售版信息管理平台V2.0"; //商家APP                 
            }

            request.pay_type_code = int.Parse(shop.pay_type_code.Split(',')[0]);

            PreOrderDto dtoOrder = await this.httpClient.OrderPreCreateByShop(request); 
            if (dtoOrder.code == 0)
            {                
                dto.data = dtoOrder.data;
                dto.data.order_id = request.order_id;
                dto.data.delivery_id = request.delivery_id;
            }
            else
            {
                dto.error = new Error() { code = dtoOrder.code, msg = dtoOrder.message };
            }
            return dto;
        }

        [HttpPost("check")]
        public async Task<DataDto> Check(OrderCheckRequest request)
        {
            DataDto dto = new DataDto();

            request.check_type = 1;
            request.mock_order_time = DateTimeUtil.DateTimeToTimeStamp(DateTime.Now);

            OrderCheckDto dtoCheck = await this.httpClient.OrderCheck(request);            
            if (dtoCheck.code != 0)
            {
                dto.error = new Error() { code = dtoCheck.code, msg = dtoCheck.message };
            }
            return dto;
        }

        [HttpPost("Create")]
        public async Task<MtpsOrderDto> Create(OrderContentEntity request)
        {
            MtpsOrderDto dto = new MtpsOrderDto();
 
            string shop_id = request.shop_id;
            ShopMtpsEntity shop = this.shopBLL.Get(shop_id);
            string msg = this.CheckOrderInfo(shop, request);
            if (msg != "")
            {
                dto.error = new Error() { code = -1, msg = msg };
                return dto;
            }

            if (request.delivery_id == 0)
            {
                request.delivery_id = DateTimeUtil.DateTimeToTimeStamp(DateTime.Now);
            }

            string order_id = "";
            request.poi_seq = this.orderContentBLL.GetOrderID(shop_id, out order_id).ToString();

            //定单
            if (string.IsNullOrEmpty(request.order_id))
            { 
                request.order_id = order_id;
            }
          
            request.coordinate_type = 0;
            if (string.IsNullOrEmpty(request.outer_order_source_desc))
            {
                request.outer_order_source_desc = "裕林医药零售版信息管理平台V2.0"; //商家APP                 
            }
            request.pay_type_code = int.Parse(shop.pay_type_code.Split(',')[0]);

            //配送码
            //if (string.IsNullOrEmpty(request.delivery_qr_code))
            //{
            //    DeliveryCodeDto2 codeDto = await this.httpClient.CreateDeliveryCode(shop_id, order_id);
            //    if (codeDto != null
            //        && codeDto.data != null
            //        && codeDto.data.business != null
            //        && codeDto.data.content != null)
            //    {
            //        request.delivery_qr_code = JsonConvert.SerializeObject(codeDto.data);
            //    }
            //}
 
            OrderDto dtoOrder = await this.httpClient.OrderCreateByShop(request);
             
            if (dtoOrder.code == 0)
            {
                dto.data = dtoOrder.data;

                //保存主表
                request.mt_peisong_id = dtoOrder.data.mt_peisong_id;
                request.CreateTime = DateTime.Now;
                long SN = this.orderContentBLL.Save(request);

                //request
                if (request.goods_detail != null && request.goods_detail.goods != null)
                {
                    foreach (OrderDetailEntity detail in request.goods_detail.goods)
                    {
                        detail.FKSN = SN;
                        this.orderContentBLL.AddDetail(detail);
                    }
                }
            }
            else
            {
                dto.error = new Error() { code = dtoOrder.code, msg = dtoOrder.message };
            }
            return dto;
        }

        /// <summary>
        /// 取消定单
        /// </summary>
        /// <param name="cancelOrder"></param>
        /// <returns></returns>
        [HttpPost("cancel")]
        public async Task<DataDto> OrderDelete(CancelOrderRequest cancelOrder)
        {
            DataDto dto = new DataDto();

            OrderDeleteDto dtoDelete = new OrderDeleteDto();
            dtoDelete = await this.httpClient.OrderDetele(cancelOrder);
            if (dtoDelete.code == 0)
            {                
                //更新数据
                OrderContentEntity orderContent = new OrderContentEntity();
                orderContent.status = 99;
                orderContent.mt_peisong_id = cancelOrder.mt_peisong_id;
                orderContent.delivery_id = cancelOrder.delivery_id;

                orderContent.delivery_id = cancelOrder.cancel_reason_id;
                orderContent.cancel_reason = cancelOrder.cancel_reason;

                int iresult = this.orderContentBLL.UpdateCancel(orderContent);
                if (iresult > 0)
                {
                    base.WriteInformation("OrderDelete", $"{cancelOrder.sign}: 取消定单成功");
                }
            }
            else
            {
                dto.error = new Error() { code = dtoDelete.code, msg = dtoDelete.message };
            }

            return dto;
        }
  
        /// <summary>
        /// 查询定单状态
        /// </summary>
        /// <param name="delivery_id"></param>
        /// <param name="mt_peisong_id"></param>
        /// <returns></returns>
        [HttpGet("status/query")]
        public async Task<OrderStatusDto> QueryStatus(long delivery_id, string mt_peisong_id)
        {
            OrderStatusDto dto = new OrderStatusDto();
            QueryStatusRequest reqeust = new QueryStatusRequest();
            reqeust.delivery_id = delivery_id;
            reqeust.mt_peisong_id = mt_peisong_id;
            dto = await this.httpClient.QueryStatus(reqeust);
            return dto;
        }

        /// <summary>
        /// 获取配送码
        /// </summary>
        /// <param name="shop_id"></param>
        /// <param name="order_id"></param>
        /// <returns></returns>
        [HttpGet("CreateDeliveryCode")]
        public async Task<DeliveryCodeDto> CreateDeliveryCode(string shop_id, string order_id)
        {
            DeliveryCodeDto dto = new DeliveryCodeDto();
            try
            {
                DeliveryCodeDto2 dto2 = await this.httpClient.CreateDeliveryCode(shop_id, order_id);
                if (dto2.code != 0)
                {
                    dto.error = new Error { code = dto2.code, msg = dto2.message };
                }
                else
                {
                    dto.data = dto2.data;
                    if (dto.data != null 
                        && !string.IsNullOrEmpty(dto.data.content) 
                        && !string.IsNullOrEmpty(dto.data.business)) 
                    {
                        string delivery_qr_code = JsonConvert.SerializeObject(dto.data);
                        this.orderContentBLL.UpdateDeliveryCode(shop_id, order_id, delivery_qr_code);
                    }
                } 
            }
            catch (Exception ex)
            {
                dto.SetException(ex);
            }
        
            return dto;
        }

        /// <summary>
        /// 获取骑手当前位置
        /// </summary>
        /// <returns></returns>
        [HttpGet("rider/location")]
        public async Task<RiderLocationDto> RiderLocation(long delivery_id, string mt_peisong_id)
        {
            RiderLocationDto dto = new RiderLocationDto();
            try
            {
                MtpsRiderLocationDto dto2 = await this.httpClient.OrderRiderLocation(delivery_id, mt_peisong_id);
                if (dto2.code != 0)
                {
                    dto.error = new Error { code = dto2.code, msg = dto2.message };
                }
                else
                {
                    dto.data = dto2.data;
                }
            }
            catch (Exception ex)
            {
                dto.SetException(ex);
            }

            return dto;
        }

        /// <summary>
        /// 订单状态回调
        /// </summary>
        /// <param name="orderStatus"></param>
        /// <returns></returns>
        [HttpPost("status/callback")]
        public IActionResult StatusCallBack([FromForm] CBOrderStatus orderStatus)
        {
            CodeDto okDto = new CodeDto();
            JsonResult jsonResult = new JsonResult(okDto);

            try
            { 
                OrderContentEntity orderContent = new OrderContentEntity(); 
                orderContent.mt_peisong_id = orderStatus.mt_peisong_id;
                orderContent.delivery_id = orderStatus.delivery_id;
                orderContent.status = orderStatus.status;
                orderContent.order_id = orderStatus.order_id;

                orderContent.courier_name = orderStatus.courier_name;
                orderContent.courier_phone = orderStatus.courier_phone;
                orderContent.cancel_reason_id = orderStatus.cancel_reason_id;
                orderContent.cancel_reason = orderStatus.cancel_reason;
                orderContent.predict_delivery_time = orderStatus.predict_delivery_time;
                 
                int iresult = this.orderContentBLL.UpdateStatus(orderContent);
                if (iresult > 0)
                {
                    base.WriteInformation("StatusCallBack", $"{orderStatus.sign}: 订单状态回调");
                }
            }
            catch (Exception ex)
            {
                okDto.code = -1;
                base.WriteException("Status", ex);
            }

            jsonResult.StatusCode = 200;
            return jsonResult;
        }

        /// <summary>
        /// 订单异常回调
        /// </summary>
        /// <param name="orderStatus"></param>
        /// <returns></returns>
        [HttpPost("exception/callback")]
        public IActionResult StatusExceCallBack([FromForm] CBOrderExceptionStatus orderStatus)
        {
            CodeDto okDto = new CodeDto();
            JsonResult jsonResult = new JsonResult(okDto);

            try
            {
                OrderContentEntity orderContent = new OrderContentEntity();
                orderContent.mt_peisong_id = orderStatus.mt_peisong_id;
                orderContent.delivery_id = orderStatus.delivery_id;
                orderContent.order_id = orderStatus.order_id;
                orderContent.exception_id = orderStatus.exception_id;
                orderContent.exception_code = orderStatus.exception_code;
                orderContent.exception_descr = orderStatus.exception_descr;
                orderContent.exception_time = orderStatus.exception_time;
                orderContent.courier_name = orderStatus.courier_name;
                orderContent.courier_phone = orderStatus.courier_phone;
                
                int iresult = this.orderContentBLL.UpdateException(orderContent);
                if (iresult > 0)
                { 
                    base.WriteInformation("StatusExceCallBack", $"{orderStatus.sign}: 订单异常回调"); 
                }
            }
            catch (Exception ex)
            {
                okDto.code = -1;
                base.WriteException("Status", ex);
            }

            jsonResult.StatusCode = 200;
            return jsonResult;
        }


        private string CheckOrderInfo(ShopMtpsEntity shop, CreateOrderByShopRequest order)
        {
            string msg = "";
            if (string.IsNullOrEmpty(order.receiver_name))
            {
                msg = "收件人名称不能为空";
            }

            if (string.IsNullOrEmpty(order.receiver_address))
            {
                msg = "收件人地址不能为空";
            }

            if (string.IsNullOrEmpty(order.receiver_phone))
            {
                msg = "收件人电话不能为空";
            }


            if (shop == null)
            {
                msg = $"请创建商店{shop.shop_id}";
            }

            if (shop.delivery_service_codes == "")
            {
                msg = $"没有签约配送服务";
            }

            if (string.IsNullOrEmpty(shop.pay_type_code))
            {
                msg = "支付方式必须是 0、账期支付 1、余额支付";
            }


            return msg;
        }

    }
}
